package com.hrpc.channelHandler.handler;

import com.hrpc.compress.Compressor;
import com.hrpc.compress.CompressorFactory;
import com.hrpc.enumeration.RequestType;
import com.hrpc.serialize.Serialize;
import com.hrpc.serialize.SerializeFactory;
import com.hrpc.transport.message.MessageFormatConstant;
import com.hrpc.transport.message.RequestPayload;
import com.hrpc.transport.message.hRpcRequest;
import com.hrpc.transport.message.hRpcResponse;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Date;

public class hRpcResponseDecoder extends LengthFieldBasedFrameDecoder {
    public hRpcResponseDecoder() {
        super(
                //找到当前报文的总长度，截取报文，截取出来的报文可以去进行解析

                //最大帧的长度，maxFrameLength，超过这个length值会直接丢弃
                MessageFormatConstant.MAX_FRAME_LENGTH,
                //长度的字段的偏移量
                MessageFormatConstant.MAGIC.length + MessageFormatConstant.VERSION_LENGTH + MessageFormatConstant.HEADER_LENGTH_LENGTH,
                //长度的字段的长度
                MessageFormatConstant.FULL_FIELD_LENGTH,
                //TODO 负载的适配长度
                -(MessageFormatConstant.MAGIC.length + MessageFormatConstant.VERSION_LENGTH + MessageFormatConstant.HEADER_LENGTH_LENGTH+MessageFormatConstant.FULL_FIELD_LENGTH),
                0);
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        Object decode = super.decode(ctx, in);
        if (decode instanceof ByteBuf byteBuf){
            return decodeFrame(byteBuf);
        }
        return null;
    }
    //解析报文
    private Object decodeFrame(ByteBuf byteBuf) {
        //1，解析魔术值
        byte[] magic=new byte[MessageFormatConstant.MAGIC.length];
        byteBuf.readBytes(magic);
        //校验魔术值
        for (int i=0;i< magic.length;i++){
            if (magic[i] != MessageFormatConstant.MAGIC[i]){
                throw new RuntimeException("魔术值不匹配！！！");
            }
        }
        //2.解析版本号
        byte b = byteBuf.readByte();
        if (b > MessageFormatConstant.VERSION){
            throw new RuntimeException("获得的版本不被支持！！！");
        }
        //3.解析头部长度
        short header_length=byteBuf.readShort();
        if (header_length != MessageFormatConstant.HEADER_LENGTH){
            throw new RuntimeException("头部长度不一致！！！");
        }
        //4.解析总长度
        int full_length = byteBuf.readInt();

        //5.响应码
        byte responseCode = byteBuf.readByte();
        //6.序列化的类型
        byte serializeType= byteBuf.readByte();
        //7.压缩的类型
        byte compressType = byteBuf.readByte();
        //8.请求ID
        long requestId = byteBuf.readLong();
        //9.时间戳
        long timeStamp = byteBuf.readLong();

        //我们需要进行封装
        hRpcResponse hRpcResponse=new hRpcResponse();
        hRpcResponse.setRequestId(requestId);
        hRpcResponse.setCompressType(compressType);
        hRpcResponse.setSerializeType(serializeType);
        hRpcResponse.setCode(responseCode);
        //响应时间戳
        hRpcResponse.setTimeStamp(timeStamp);
        //TODO 如果是心跳请求则没有负载，此处可以判断直接返回
//        if (requestType == RequestType.HEART_BEAT.getId()){
//            return hRpcRequest;
//        }

        //9.请求体，负载
        int body_length=full_length - header_length;
        byte[] payload=new byte[body_length];
        //读到payload中
        byteBuf.readBytes(payload);
        //有了字节数组之后就可以解压缩、反序列化
        //1.解压缩
        Object body=new Object();
        if (payload != null && payload.length!=0){
            Compressor compressor = CompressorFactory.getCompressor(compressType).getImpl();
            payload = compressor.deCompress(payload);
            //2.反序列化
            Serialize serialize=SerializeFactory.getSerialize(hRpcResponse.getSerializeType()).getImpl();
            body = serialize.deSerialize(payload, Object.class);
        }

        hRpcResponse.setBody(body);
        return hRpcResponse;
    }
}
